// 他に割込を使ってない場面で使用。

#include "defines.h"
#include "delay.h"
#include "intr.h"
#include "interrupt.h"

#define TSTR    ((volatile uint8 *) 0xffff60)
#define TISRA   ((volatile uint8 *) 0xffff64)
#define TCR16_0 ((volatile uint8 *) 0xffff68)
#define GRA_0    ((volatile uint16 *)0xffff6c)
#define TCNT16_0  ((volatile uint16 *)0xffff6a)

void delay_us(uint16 usec)
{   
    uint16 i;

    *TCR16_0 = 0x20;
    *GRA_0 = 0x0013;
    *TCNT16_0 = 0x0000;
    *TISRA &= ~0x01;
    
    *TSTR |= 0x01;

    for (i = 0; i < usec; i++) {
        while(!(*TISRA & 0x01))
            ;
        *TISRA &= ~0x01;
    }
    
    *TSTR &= ~0x01;
}

void delay_ms(uint16 msec)
{    
    uint16 i;    

    *TCR16_0 = 0x23;
    *GRA_0 = 0x09c3;
    *TCNT16_0 = 0x0000;
    *TISRA &= ~0x01;
    
    *TSTR |= 0x01;

    for (i = 0; i < msec; i++) {
        while(!(*TISRA & 0x01))
            ;
        *TISRA &= ~0x01;
    }
    
    *TSTR &= ~0x01;
}

#define TCR8_0   ((volatile uint8 *) 0xffff80)
#define TCR8_1   ((volatile uint8 *) 0xffff81)
#define TCORA    ((volatile uint16 *)0xffff84)
#define TCNT8    ((volatile uint16 *) 0xffff88)
#define TCSR8_0  ((volatile uint8 *) 0xffff82)
#define TCSR8_1  ((volatile uint8 *) 0xffff83)

void delay_s(uint16 sec)
{   
    uint16 s;
    int i;

    *TCR8_0 = 0x00;
    *TCR8_1 = 0x0c;
    *TCORA = 0xf9f9;
    *TCNT8 = 0;
    *TCSR8_1 = 0x00;
    
    *TCR8_0 = 0x0a;

    for (s = 0; s < sec; s++) {
        for (i = 0; i < 5; i++) {
            while(!(*TCSR8_1 & 0x40))
                ;
            *TCSR8_1 &= ~0x40;
        }
    }
}

// タイムアウトとdelay_sは同時に使えない

static int timeout = 0;

int is_timeout()
{
    return timeout;
}

static void intr(softvec_type_t type, unsigned long sp)
{
    timeout = 1;
    *TCR8_1 = 0x00;
    *TCSR8_0 &= ~0x40;
}

void timeout_init(uint16 sec) // secは1～26
{
    uint16 tcora = 0, i;
    *TCR8_1 = 0x00;
    *TCR8_0 = 0x4c;
    for (i = 0; i < sec; i++) {
        tcora += 0x98a;
    }
    *TCORA = tcora;
    *TCSR8_0 = 0x00;
    softvec_setintr(SOFTVEC_TYPE_T8INTR_01, intr);
    INTR_ENABLE;
}

void timeout_start()
{
    *TCR8_1 = 0x00;
    *TCNT8 = 0;
    *TCR8_1 = 0x03;
    timeout = 0;
}

void timeout_stop()
{
    *TCR8_1 = 0x00;
}

void timeout_end()
{
    INTR_DISABLE;
    *TCR8_0 = 0x00;
    *TCR8_1 = 0x00;
    softvec_setintr(SOFTVEC_TYPE_T8INTR_01, NULL);
}
